package com.leinbo.onedoc.utils

import com.leinbo.onedoc.utils.LogUtils
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.util.*

/**
 * Created by sundaiyue on 2022/11/28 02:23
 */

object Register {
    private val com = intArrayOf(99, 111, 109, 46, 97, 115, 112, 111, 115, 101)
    private val MS_OFFICE = String(com, 0, com.size)

    /**
     * for asp-words:jdk17:22.5 版本
     */
    @Throws(Exception::class)
    fun registerWord_v_22_5() {
        val zzjXClass = Class.forName("$MS_OFFICE.words.zzjX")
        val constructor: Constructor<*> = zzjXClass.declaredConstructors[0]
        constructor.isAccessible = true
        val zzjXInstance: Any = constructor.newInstance()

        // zzZ7O
        val zzZ7O: Field = zzjXClass.getDeclaredField("zzZ7O")
        zzZ7O.isAccessible = true
        zzZ7O.set(zzjXInstance, Date(Long.MAX_VALUE))

        // zzBf
        val zzZfB: Field = zzjXClass.getDeclaredField("zzZfB")
        zzZfB.isAccessible = true
        val zzYP3Class = Class.forName("$MS_OFFICE.words.zzYP3")
        val zzBfField: Field = zzYP3Class.getDeclaredField("zzBf")
        zzBfField.isAccessible = true
        zzZfB.set(zzjXInstance, zzBfField.get(null))

        // zzZjA
        val zzZjA: Field = zzjXClass.getDeclaredField("zzZjA")
        zzZjA.isAccessible = true
        zzZjA.set(null, zzjXInstance)
        val zzCnClass = Class.forName("$MS_OFFICE.words.zzCn")
        val zzZyx: Field = zzCnClass.getDeclaredField("zzZyx")
        zzZyx.isAccessible = true
        zzZyx.set(null, 128)
        val zzZ8w: Field = zzCnClass.getDeclaredField("zzZ8w")
        zzZ8w.isAccessible = true
        zzZ8w.set(null, false)
    }

    /**
     * asp-cells:22.6 版本有效
     */
    @Throws(Exception::class)
    fun registerExcel_v_22_6() {
        val licenseExpiry = "20991231"

        // License
        val licenseClass = Class.forName("$MS_OFFICE.cells.License")
        val a: Field = licenseClass.getDeclaredField("a")
        a.isAccessible = true
        a.set(null, licenseExpiry)

        // k65
        val k65Class = Class.forName("$MS_OFFICE.cells.k65")
        val k65A: Field = k65Class.getDeclaredField("a")
        k65A.isAccessible = true
        val constructor: Constructor<*> = k65Class.declaredConstructors.first()
        constructor.isAccessible = true
        val k65Instance: Any = constructor.newInstance()
        k65A.set(null, k65Instance)
        val k56C: Field = k65Class.getDeclaredField("c")
        k56C.isAccessible = true
        k56C.set(k65Instance, licenseExpiry)

        // e0n
        val e0nClass = Class.forName("$MS_OFFICE.cells.e0n")
        val e0nA: Field = e0nClass.getDeclaredField("a")
        e0nA.setAccessible(true)
        e0nA.set(null, false)
    }

    /**
     * asp-slides:21.10 版本有效
     */
    @Throws(Exception::class)
    fun registerPPT_v_21_10() {
        val licenseExpiry = Date(Long.MAX_VALUE)
        val publicClass = Class.forName("$MS_OFFICE.slides.internal.of.public")
        val publicInstance = publicClass.declaredConstructors.first().newInstance()
        val publicTry: Field = publicClass.getDeclaredField("try")
        publicTry.isAccessible = true
        publicTry.set(null, publicInstance)
        val publicInt: Field = publicClass.getDeclaredField("int")
        publicInt.setAccessible(true)
        publicInt.set(publicInstance, licenseExpiry)
        val publicNew: Field = publicClass.getDeclaredField("new")
        publicNew.setAccessible(true)
        publicNew.set(publicInstance, licenseExpiry)
        val publicIf: Field = publicClass.getDeclaredField("if")
        publicIf.setAccessible(true)
        publicIf.set(publicInstance, 2)
        val nativeClass = Class.forName("$MS_OFFICE.slides.internal.of.native")
        val nativeDo: Field = nativeClass.getDeclaredField("do")
        nativeDo.isAccessible = true
        nativeDo.set(null, publicInstance)
    }

    /**
     * aspose-pdf:21.7 版本有效
     */
    @Throws(Exception::class)
    fun registerPdf_v_21_7() {
        val licenseExpiry = Date(Long.MAX_VALUE)
        val l9yClass = Class.forName("$MS_OFFICE.pdf.l9y")
        val constructor: Constructor<*> = l9yClass.declaredConstructors[0]
        constructor.setAccessible(true)
        val l9yInstance: Any = constructor.newInstance()

        // lc
        val lc: Field = l9yClass.getDeclaredField("lc")
        lc.isAccessible = true
        lc.set(l9yInstance, licenseExpiry)
        // ly
        val ly: Field = l9yClass.getDeclaredField("ly")
        ly.isAccessible = true
        ly.set(l9yInstance, licenseExpiry)

        // l0if
        val l0if: Field = l9yClass.getDeclaredField("l0if")
        l0if.isAccessible = true
        val l9nClass = Class.forName("$MS_OFFICE.pdf.l9n")
        val lfField: Field = l9nClass.getDeclaredField("lf")
        lfField.isAccessible = true
        val lf: Any = lfField.get(null) // 处理枚举
        l0if.set(l9yInstance, lf)
        val l9yLfClass = Class.forName("$MS_OFFICE.pdf.l9y\$lf")
        val `l9y$lf`: Field = l9yLfClass.getDeclaredField("lI")
        `l9y$lf`.isAccessible = true
        `l9y$lf`.set(null, l9yInstance)
        val l19jClass = Class.forName("$MS_OFFICE.pdf.l19j")
        val l19jlI: Field = l19jClass.getDeclaredField("lI")
        l19jlI.isAccessible = true
        l19jlI.set(null, 128)
        val l19jLf: Field = l19jClass.getDeclaredField("lf")
        l19jLf.isAccessible = true
        l19jLf.set(null, false)
    }

    fun registerAll() {
        LogUtils.log("Registering...")
        try {
            registerWord_v_22_5()
            registerPPT_v_21_10()
            registerExcel_v_22_6()
            registerPdf_v_21_7()
        } catch (e: Exception) {
            throw RuntimeException("Registered failed!", e)
        }
        Locale.setDefault(Locale("zh", "cn"));
        LogUtils.log("Registered successfully!")

        println(
            """
                ..................]]]]]]`....
                ..............,@@@[`...,\@@@.
                ..............@@@`.......=@@/
                .............,/@@@@@@@@@@@/`.
                .........,/@@@/`.............
                .....,/@@@@@@@`..............
                .,/@@@@/\@@@]................""".trimIndent()
        )
    }
}
